package com.guli.gulimall.product.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.guli.common.utils.R;
import com.guli.gulimall.product.config.GuliEsConfig;
import com.guli.gulimall.product.dao.*;
import com.guli.gulimall.product.entity.*;
import com.guli.gulimall.product.feign.CouponFeignService;
import com.guli.gulimall.product.service.*;
import com.guli.gulimall.product.to.MemberPriceTo;
import com.guli.gulimall.product.to.SkuFullReductionTo;
import com.guli.gulimall.product.to.SkuLadderTo;
import com.guli.gulimall.product.to.SpuBoundsTo;
import com.guli.gulimall.product.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guli.common.utils.PageUtils;
import com.guli.common.utils.Query;


/**
 * @author 6y
 */
@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

	@Autowired
	private SpuInfoDescDao spuInfoDescDao;
	@Autowired
	private BrandDao brandDao;
	@Autowired
	private CategoryDao categoryDao;
	@Autowired
	private SpuImagesService spuImagesService;
	@Autowired
	private AttrDao attrDao;
	@Autowired
	private ProductAttrValueService productAttrValueService;
	@Autowired
	private SkuInfoDao skuInfoDao;
	@Autowired
	private SkuImagesService skuImagesService;
	@Autowired
	private SkuSaleAttrValueService skuSaleAttrValueService;
	@Autowired
	private CouponFeignService couponFeignService;
	@Autowired
	private RestHighLevelClient restHighLevelClient;

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		QueryWrapper<SpuInfoEntity> w = new QueryWrapper<>();
		String key = (String) params.get("key");
		String catalogId = (String) params.get("catalogId");
		String brandId = (String) params.get("brandId");
		String status = (String) params.get("status");
		if (StringUtils.isNotEmpty(key)) {
			w.and(qw ->
					qw.like("spu_name", key).or().eq("id", key)
			);
		}
		if (StringUtils.isNotEmpty(catalogId) && !"0".equals(catalogId)) {
			w.eq("catalog_id", catalogId);
		}
		if (StringUtils.isNotEmpty(brandId) && !"0".equals(brandId)) {
			w.eq("brand_id", brandId);
		}
		if (StringUtils.isNotEmpty(status)) {
			w.eq("publish_status", status);
		}

		IPage<SpuInfoEntity> page = this.page(
				new Query<SpuInfoEntity>().getPage(params),
				w
		);

		return new PageUtils(page);
	}

	@Override
	public void saveSpu(SpuInfoVo spuInfoVo) {

		//1、pms_spu_info 商品基本信息表
		SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
		BeanUtils.copyProperties(spuInfoVo, spuInfoEntity);
		spuInfoEntity.setCreateTime(new Date());
		spuInfoEntity.setUpdateTime(new Date());
		baseMapper.insert(spuInfoEntity);
		//2. pms_spu_info_desc 商品介绍表（大图图片路径表）
		//2.1从vo中获取图片信息，创建图片的实体类--同步数据库
		SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
		String join = StringUtils.join(spuInfoVo.getDecript(), ",");
		spuInfoDescEntity.setSpuId(spuInfoEntity.getId());
		spuInfoDescEntity.setDecript(join);
		spuInfoDescDao.insert(spuInfoDescEntity);
		//3. pms_spu_images 商品图集表（jd左上角商品介绍图）
		//一张图片一条数据，这是一个批量添加 我们的mapper层没有批量保存的方法 service中批量操作额方法，注入service 实现批量添加
		if (!spuInfoVo.getImages().isEmpty()) {
			List<SpuImagesEntity> collect = spuInfoVo.getImages().stream().map(imgUrl -> {
				SpuImagesEntity spuImagesEntity = new SpuImagesEntity();
				spuImagesEntity.setSpuId(spuInfoEntity.getId());
				spuImagesEntity.setImgUrl(imgUrl);
				spuImagesEntity.setImgSort(0);
				return spuImagesEntity;
			}).collect(Collectors.toList());
			spuImagesService.saveBatch(collect);
		}
		//4. pms_product_attr_value 商品的属性表
		//页面中可以选择商品的规格参数，并且保存对应的值
		//4.1根据属性编号查询属性名称，同步数据库
		List<BaseAttrs> baseAttrs = spuInfoVo.getBaseAttrs();
		if (!baseAttrs.isEmpty()) {
			List<ProductAttrValueEntity> collect = baseAttrs.stream().map(attr -> {
				ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
				productAttrValueEntity.setSpuId(spuInfoEntity.getId());
				productAttrValueEntity.setAttrId(attr.getAttrId());
				productAttrValueEntity.setAttrValue(attr.getAttrValues());
				productAttrValueEntity.setQuickShow(attr.getShowDesc());
				productAttrValueEntity.setAttrSort(0);
				AttrEntity attrEntity = attrDao.selectById(attr.getAttrId());
				productAttrValueEntity.setAttrName(attrEntity.getAttrName());
				productAttrValueEntity.setSearchType(attrEntity.getSearchType());
				return productAttrValueEntity;
			}).collect(Collectors.toList());
			productAttrValueService.saveBatch(collect);
		}
		//        ----------spu的基本信息保存束------------------
		//设置销售信息。生成sku列表
		List<Skus> skus = spuInfoVo.getSkus();
		for (Skus sku : skus) {
			//5. pms_sku_info sku基本信息表（外键spuId）
			//5.1 获取默认图片
			//        添加默认图片
			SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
			skuInfoEntity.setSpuId(spuInfoEntity.getId());
			skuInfoEntity.setSkuName(sku.getSkuName());
			skuInfoEntity.setSkuDesc(spuInfoEntity.getSpuDescription());
			skuInfoEntity.setCatalogId(spuInfoEntity.getCatalogId());
			skuInfoEntity.setBrandId(spuInfoEntity.getBrandId());
			//默认图
			List<Images> images = sku.getImages();
			if (!images.isEmpty()) {
				Images defaultImg = images.stream().filter(img -> {
					return img.getDefaultImg().equals(1);
				}).findFirst().get();
				skuInfoEntity.setSkuDefaultImg(defaultImg.getImgUrl());
			}
			skuInfoEntity.setSkuSubtitle(sku.getSkuSubtitle());
			skuInfoEntity.setPrice(sku.getPrice());
			skuInfoEntity.setSaleCount(0L);
			skuInfoDao.insert(skuInfoEntity);
			//6. pms_sku_images sku的图片信息（保存每个sku的图片信息）
			List<SkuImagesEntity> skuImagesEntities = new ArrayList<>();
			if (!images.isEmpty()) {
				List<SkuImagesEntity> collect = images.stream().map(image -> {
					SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
					skuImagesEntity.setSkuId(skuInfoEntity.getSkuId());
					skuImagesEntity.setImgUrl(image.getImgUrl());
					skuImagesEntity.setImgSort(0);
					skuImagesEntity.setDefaultImg(image.getDefaultImg());
					return skuImagesEntity;
				}).collect(Collectors.toList());
				//是一个批量添加
				skuImagesService.saveBatch(skuImagesEntities);
			}
			//7. pms_sku_sale_attr_value sku的销售属性表
			//保存的页面选择的所有的销售属性信息
			//一个销售属性一条数据（skuId有关）
			if (!sku.getAttr().isEmpty()) {
				List<SkuSaleAttrValueEntity> collect = sku.getAttr().stream().map(attr -> {
					SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
					skuSaleAttrValueEntity.setSkuId(skuInfoEntity.getSkuId());
					skuSaleAttrValueEntity.setAttrId(attr.getAttrId());
					skuSaleAttrValueEntity.setAttrName(attr.getAttrName());
					skuSaleAttrValueEntity.setAttrValue(attr.getAttrValue());
					skuSaleAttrValueEntity.setAttrSort(0);
					AttrEntity attrEntity = attrDao.selectById(attr.getAttrId());
					skuSaleAttrValueEntity.setSearchType(attrEntity.getSearchType());
					return skuSaleAttrValueEntity;
				}).collect(Collectors.toList());
				//批量添加
				skuSaleAttrValueService.saveBatch(collect);
			}
			//        ----------sku的基本信息保存结束------------------
			//        -------------优惠券表添加数据（feign调用）--------------
			//        ---------------满减和打折表----------------------
			// 8. sms_sku_ladder 打折表（sku级别）
			SkuLadderTo skuLadderTo = new SkuLadderTo();
			skuLadderTo.setSkuId(skuInfoEntity.getSkuId());
			skuLadderTo.setFullCount(sku.getFullCount());
			skuLadderTo.setDiscount(sku.getDiscount());
			skuLadderTo.setAddOther(sku.getCountStatus());
			skuLadderTo.setPrice(sku.getPrice().multiply(sku.getDiscount()).multiply(new BigDecimal(sku.getFullCount().intValue())));
			couponFeignService.saveSkuLadder(skuLadderTo);
			// 9. sms_sku_full_reduction (满减表，sku级别)
			SkuFullReductionTo skuFullReductionTo = new SkuFullReductionTo();
			skuFullReductionTo.setSkuId(skuInfoEntity.getSkuId());
			skuFullReductionTo.setFullPrice(sku.getFullPrice());
			skuFullReductionTo.setReducePrice(sku.getReducePrice());
			skuFullReductionTo.setAddOther(sku.getPriceStatus());
			couponFeignService.saveSkuFullReduction(skuFullReductionTo);
			//	10. sms_member_price (会员等级价格表)
			//	feign调用批量添加
			//	        商品sku添加结束
			List<MemberPrice> memberPrices = sku.getMemberPrice();
			if (!memberPrices.isEmpty()) {
				List<MemberPriceTo> collect = memberPrices.stream().map(memberPrice -> {
					MemberPriceTo memberPriceTo = new MemberPriceTo();
					memberPriceTo.setSkuId(skuInfoEntity.getSkuId());
					memberPriceTo.setMemberLevelId(memberPrice.getId());
					memberPriceTo.setMemberLevelName(memberPrice.getName());
					memberPriceTo.setMemberPrice(memberPrice.getPrice());
					return memberPriceTo;
				}).collect(Collectors.toList());
				couponFeignService.saveMemberPrices(collect);
			}
		}
		//	11. sms_spu_bounds 积分和金币表 spu级别
		//	两个微服务之间数据传递的实体类 我们称为to
		//	使用feign调用添加积分和金币
		SpuBoundsTo spuBoundsTo = new SpuBoundsTo();
		spuBoundsTo.setSpuId(spuInfoEntity.getId());
		spuBoundsTo.setGrowBounds(spuInfoVo.getBounds().getGrowBounds());
		spuBoundsTo.setBuyBounds(spuInfoVo.getBounds().getBuyBounds());
		couponFeignService.saveSpuBounds(spuBoundsTo);
	}

	@Override
	public R up(Long sid) {

		try {
			SpuInfoEntity spuInfo = baseMapper.selectById(sid);
			//需要检索的规格参数
			QueryWrapper<ProductAttrValueEntity> w2 = new QueryWrapper<>();
			w2.eq("spu_id", sid);
			w2.eq("search_type", 1);
			List<ProductAttrValueEntity> baseAttrList = productAttrValueService.list(w2);
			List<SkuEsVo.SkuAttr> collect = null;
			if (!baseAttrList.isEmpty()) {
				//把数据库查询到的数据复制到vo中
				collect = baseAttrList.stream().map(attr -> {
					SkuEsVo.SkuAttr skuBaseAttr = new SkuEsVo.SkuAttr();
					skuBaseAttr.setAttrId(attr.getAttrId());
					skuBaseAttr.setAttrName(attr.getAttrName());
					skuBaseAttr.setAttrValue(attr.getAttrValue());
					return skuBaseAttr;
				}).collect(Collectors.toList());
			}
			//对应sku列表
			QueryWrapper<SkuInfoEntity> w1 = new QueryWrapper<>();
			w1.eq("spu_id", sid);
			List<SkuInfoEntity> skuList = skuInfoDao.selectList(w1);
			BulkRequest bulkRequest = new BulkRequest("product");
			if (!skuList.isEmpty()) {
				for (SkuInfoEntity sku : skuList) {
					IndexRequest indexRequest = new IndexRequest();
					SkuEsVo skuEsVo = new SkuEsVo();
					skuEsVo.setSkuId(sku.getSkuId());
					skuEsVo.setSpuId(sku.getSpuId());
					skuEsVo.setSkuTitle(sku.getSkuTitle());
					skuEsVo.setSkuPrice(sku.getPrice());
					skuEsVo.setSkuImg(sku.getSkuDefaultImg());
					skuEsVo.setSaleCount(sku.getSaleCount());
					skuEsVo.setHasStock(true);
					skuEsVo.setHotScore(0L);
					skuEsVo.setBrandId(spuInfo.getBrandId());
					BrandEntity brandEntity = brandDao.selectById(spuInfo.getBrandId());
					skuEsVo.setBrandImg(brandEntity.getLogo());
					skuEsVo.setBrandName(brandEntity.getName());
					skuEsVo.setCatalogId(spuInfo.getCatalogId());
					CategoryEntity categoryEntity = categoryDao.selectById(spuInfo.getCatalogId());
					skuEsVo.setCatalogName(categoryEntity.getName());
					QueryWrapper<SkuSaleAttrValueEntity> w3 = new QueryWrapper<>();
					w3.eq("sku_id", sku.getSkuId());
					w3.eq("search_type", 1);
					List<SkuSaleAttrValueEntity> saleList = skuSaleAttrValueService.list(w3);
					if (!saleList.isEmpty()) {
						//把数据库查询到的数据复制到vo中
						List<SkuEsVo.SkuAttr> collect1 = saleList.stream().map(attr -> {
							SkuEsVo.SkuAttr skuBaseAttr = new SkuEsVo.SkuAttr();
							skuBaseAttr.setAttrId(attr.getAttrId());
							skuBaseAttr.setAttrName(attr.getAttrName());
							skuBaseAttr.setAttrValue(attr.getAttrValue());
							return skuBaseAttr;
						}).collect(Collectors.toList());
						//数据合并
						if (collect != null) {
							collect1.addAll(collect);
						}
						skuEsVo.setAttrs(collect1);
					}
					indexRequest.id(sku.getSkuId().toString());
					String json = JSONObject.toJSONString(skuEsVo);
					indexRequest.source(json, XContentType.JSON);
					bulkRequest.add(indexRequest);
				}
				restHighLevelClient.bulk(bulkRequest, GuliEsConfig.COMMON_OPTIONS);
				//上架状态
				spuInfo.setPublishStatus(1);
				baseMapper.updateById(spuInfo);
				return R.ok();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return R.error();
	}
}
